package cool.taomu.toolkit.service.client.kademlia.utils

import com.google.common.base.Optional
import cool.taomu.toolkit.retry.Retry
import cool.taomu.toolkit.service.kademlia.thrift.KademliaService
import java.net.SocketTimeoutException
import java.util.concurrent.CompletableFuture
import java.util.function.Function
import org.apache.commons.pool2.impl.GenericObjectPool
import org.apache.thrift.protocol.TCompactProtocol
import org.apache.thrift.transport.TTransport
import org.apache.thrift.transport.layered.TFramedTransport
import org.slf4j.LoggerFactory

class ClientExec {
   val static LOG = LoggerFactory.getLogger(ClientExec);

    @Retry(maxAttempts=3, delay=500, exponentialBackoff=true, rateLimit=2.0)
    def <T> CompletableFuture<Optional<T>> clientExec(GenericObjectPool<TTransport> cpool,
        Function<KademliaService.Client, T> func) {
        var socket = cpool.borrowObject
        try(var tTransport = new TFramedTransport(socket, Integer.MAX_VALUE)) {
            var protocol = new TCompactProtocol(tTransport);
            var client = new KademliaService.Client(protocol);
            try {
                var r = CompletableFuture.completedFuture(Optional.fromNullable(func.apply(client)));
                return r
            } catch (SocketTimeoutException stex) {
                throw stex
            }
        } catch (Exception ex) {
            if (socket !== null) {
                LOG.debug("socket标记为无效")
                cpool.invalidateObject(socket) // 标记为无效
            }
            throw ex
        } finally {
            if (socket !== null) {
                cpool.returnObject(socket)
            }
        }
    // return CompletableFuture.completedFuture(Optional.absent);
    } 
}